第 16 屆 iThome 鐵人賽 (2023)
{%hackmd BJrTq20hE %}
已經完成訓練模型, 現在要使用 test 測試資料來評估模型準確率.
- # 1.評估模型準確率 # 使用下面代碼評估模型準確率:
scores = model.evaluate(x_Test_norm, y_TestOneHot)
print()
print("\t[Info] Accuracy of testing data = {:2.1f}%".format(scores[1]*100.0))
>>>[Info] Accuracy of testing data = 97.6%
# 進行預測
print("\t[Info] Making prediction to x_Test_norm")
prediction = model.predict(x_Test_norm)
prediction = np.argmax(prediction,axis=1)
print()
print("\t[Info] Show 10 prediction result (From 240):")
print("%s\n" % (prediction[240:250]))
plot_images_labels_predict(X_test_image, y_test_label, prediction, idx=240)
>>>[Info] Making prediction to x_Test_norm
>>>313/313 [==============================] - 0s 1ms/step
>>>[Info] Show 10 prediction result (From 240):
[5 9 8 7 2 3 0 6 4 2]
prediction = model.predict_classes(x_Test_norm)
predict_classes()函數在 TensorFlow 2.6 版本中被移除了以:
prediction = (model.predict(x_Test_norm) > 0.5).astype(“int32”)
prediction = model.predict(x_Test_norm)
prediction = np.argmax(prediction,axis=1)
最後選擇第二選擇,因為前者為二進制
# 1.使用 pandas crosstab 建立混淆矩陣 (Confusion matrix)
print("\t[Info] Display Confusion Matrix:")
import pandas as pd
print("%s\n" % pd.crosstab(y_test_label, prediction, rownames=['label'], colnames=['predict']))
對角線是預測結果正確的數字, 我們發現類別 “1” 的預測準確率最高共有 1,125 筆; 類別 “5” 的準確率最低共有 852 筆.
其他非對角線的數字, 代表將某一類別預測成其他類別的錯誤. 例如將類別 “5” 預測成 “3” 共發生 12 次.
# 2.建立真實與預測的 dataframe
# 如找出那些 label 結果為 "5" 的結果被預測成 "3" 的資料, 所以建立的下面的 dataframe:
df = pd.DataFrame({'label':y_test_label, 'predict':prediction})
df[:2] # 顯示前兩筆資料
# 3.查詢 label=5; prediction=3 的資料
# Pandas Dataframe 可以讓你很方便的查詢資料:
out = df[(df.label==5) & (df.predict==3)] # 查詢 label=5; predict=3 的 records
out.__class__ # 輸出是另一個 DataFrame
print(out)
# 4.查看第 340 筆資料
plot_images_labels_predict(X_test_image, y_test_label, prediction, idx=340, num=1)
#1. 修改模型
from keras.models import Sequential
from keras.layers import Dense
model = Sequential() # Build Linear Model
model.add(Dense(units=1000, input_dim=784, kernel_initializer='normal', activation='relu')) # Modify hidden layer from 256 -> 1000
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
print("\t[Info] Model summary:")
model.summary()
print("")
show_train_history(train_history,'accuracy','val_accuracy')
檢視執行結果
從下面的 “accuracy” vs “validation accuracy” 的圖可以看出兩者差距拉大 (training accuracy > validation accuracy), 說明 Overfitting 問題變嚴重
#1. 修改隱藏層加入 DropOut 功能
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout # ***** Import DropOut mooule *****
model = Sequential()
model.add(Dense(units=1000, input_dim=784, kernel_initializer='normal', activation='relu'))
model.add(Dropout(0.5)) # ***** Add DropOut functionality *****
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
print("\t[Info] Model summary:")
model.summary()
print("")
show_train_history(train_history,'accuracy','val_accuracy')
檢視進行訓練後結果
最後一個 Epoch 的執行結果可以發現 acc 與 val_acc 接近許多, 說明 Overfitting 問題有被解決.
#1. 變更模型使用兩個 Hidden Layers 並加入 DropOut 功能
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout # Import DropOut mooule
model = Sequential() # Build Linear Model
model.add(Dense(units=1000, input_dim=784, kernel_initializer='normal', activation='relu')) # Add Input/ first hidden layer
model.add(Dropout(0.5)) # Add DropOut functionality
model.add(Dense(units=1000, kernel_initializer='normal', activation='relu')) # Add second hidden layer
model.add(Dropout(0.5)) # Add DropOut functionality
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax')) # Add Hidden/output layer
print("\t[Info] Model summary:")
model.summary()
print("")
show_train_history(train_history,'accuracy','val_accuracy')
進行訓練並察看結果
由 accuracy 圖可以看出 training accuracy 與 validation accuracy 已經相當接近, 說明 Overfitting 的影響又被改善了
多層感知器 Multilayer perceptron 模型,辨識手寫字嘗試將模型加寬加深,加入drop以提高準確度,避免 overfitting ,但多層感知器有其極限,若要提高準確度,就要使用卷積神經網路 CNN .